#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
/*
 * Copyright © 2014, Finium Sdn Bhd, All Rights Reserved
 * 
 * NullCacheEventListener.java
 * Modification History
 * *************************************************************
 * Date				Author						Comment
 * Oct 10, 2012		Venkaiah Chowdary Koneru	Created
 * *************************************************************
 */
package ${package}.support;

import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import net.sf.ehcache.event.CacheEventListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * EhCache event listener for preventing caching of null values in cache data
 * store.
 * 
 * @author Venkaiah Chowdary Koneru
 */
public class NullCacheEventListener implements CacheEventListener
{
    /**
     * Singleton instance for this listener class.
     */
    public static final CacheEventListener INSTANCE = new NullCacheEventListener();

    private static final Log LOG = LogFactory
            .getLog(NullCacheEventListener.class);

    private static final String LOG_STR = "An element with key [%s] is %s %s cache [%s].";
    private static final String LOG_FROM = "from";
    private static final String LOG_TO = "to";
    private static final String LOG_IN = "in";
    private static final String LOG_EVICTED = "evicted";
    private static final String LOG_ADDED = "added";
    private static final String LOG_REMOVED = "removed";
    private static final String LOG_UPDATED = "updated";
    private static final String LOG_EXPIRED = "expired";
    private static final String LOG_NULL_REFERRENCE = "having null referrence";

    /**
     * {@inheritDoc}
     */
    @Override
    public void dispose()
    {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void notifyElementEvicted(Ehcache cache, Element element)
    {
        LOG.debug(String.format(LOG_STR, element.getKey(), LOG_EVICTED,
                LOG_FROM, cache.getName()));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void notifyElementExpired(Ehcache cache, Element element)
    {
        LOG.debug(String.format(LOG_STR, element.getKey(), LOG_EXPIRED,
                LOG_FROM, cache.getName()));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void notifyElementPut(Ehcache cache, Element element)
    {
        LOG.debug(String.format(LOG_STR, element.getKey(), LOG_ADDED, LOG_TO,
                cache.getName()));

        removeIfNull(cache, element);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void notifyElementRemoved(Ehcache cache, Element element)
    {
        LOG.debug(String.format(LOG_STR, element.getKey(), LOG_REMOVED,
                LOG_FROM, cache.getName()));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void notifyElementUpdated(Ehcache cache, Element element)
    {
        LOG.debug(String.format(LOG_STR, element.getKey(), LOG_UPDATED,
                LOG_FROM, cache.getName()));
        removeIfNull(cache, element);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void notifyRemoveAll(Ehcache cache)
    {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Object clone() throws CloneNotSupportedException
    {
        throw new CloneNotSupportedException("Singleton instance");
    }

    /**
     * helper method to remove null elements from the cache.
     * 
     * @param cache
     *            cache name
     * @param element
     *            element object
     */
    private void removeIfNull(final Ehcache cache, final Element element)
    {
        if (element.getObjectValue() == null)
        {

            LOG.debug(String.format(LOG_STR, element.getKey(),
                    LOG_NULL_REFERRENCE, LOG_IN, cache.getName()));

            LOG.trace("removeing the null key...");
            cache.remove(element.getKey());
            LOG.trace("removed null key from cache...");
        }
    }
}
